/** 
 * @Title: CalculateWord.java 
 * @Package wordrs 
 * @Description: TODO
 * @author HeYan
 * @date 2016年10月10日 上午10:38:05 
 */
package wordrelationship.dao;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import com.zizo.util.ConnectionPool;

/**
 * @ClassName: CalculateWord
 * @Description: TODO 计算词对关系
 * @author HeYan
 * @date 2016年10月10日 上午10:38:05
 * 
 */
public class CalculateWord implements Runnable {
	private String tablename;
	private Connection conn;

	/**
	 * @param tablename
	 * @param conn
	 */
	public CalculateWord(String tablename, Connection conn) {
		super();
		this.tablename = tablename;
		this.conn = conn;
	}

	/**
	 * @Title: getTables
	 * @Description: TODO 得到所有的文件名称，已做遍历
	 * @return
	 * @return List<String>
	 * @author HeYan
	 */
	public List<String> getTables() {
		List<String> tablename = new ArrayList<>();
		File file = new File("/var/server/java/heyan/file10/");
		File[] files = file.listFiles();
		for (File f : files) {
			tablename.add(f.getName());
		}
		return tablename;
	}

	/**
	 * @Title: readFileContent
	 * @Description: TODO 读取文件的内容
	 * @throws IOException
	 * @return void
	 * @author HeYan
	 */
	public void readFileContent() throws IOException {
		File file = new File("/var/server/java/heyan/file10/" + tablename);
		BufferedReader br = new BufferedReader(new FileReader(file));
		String temp = "";
		while ((temp = br.readLine()) != null) {
			calculate(temp);
		}
		br.close();
	}

	/**
	 * @Title: calculate
	 * @Description: TODO 计算词对关系
	 * @param content
	 * @return void
	 * @author HeYan
	 */
	public final void calculate(String content) {
		String[] cs = content.split("\n");
		for (String s : cs) {
			List<Term> wordTerm = HanLP.segment(s.trim().toUpperCase());// 该段话中所有的分词集合
			Map<String, Integer> map = new HashMap<>();// 计算一段话中每个词对应出现的次数
			for (Term term : wordTerm) {
				if (map.keySet().contains(term.word)) {
					map.put(term.word, map.get(term.word) + 1);
				} else {
					map.put(term.word, 1);
				}
			}
			Object[] arr = map.keySet().toArray();
			int size = arr.length;
			for (int i = 0; i < size; i++) {
				for (int j = i + 1; j < size; j++) {
					String w1 = (String) arr[i];
					String w2 = (String) arr[j];
					if (w1.equals("\\}\\{") || w2.equals("\\}\\{")) {
						continue;
					}
					int c1 = map.get(w1);
					int c2 = map.get(w2);
					int n0 = c1 > c2 ? c2 : c1;// 共现频次
					/* 计算俩个词之间 }{ 的平均个数 */
					double x = getAvgCount(w1, w2, c1, c2, s);
					double res = n0 / (Math.pow(1.3, x));
					insertRes(w1, w2, res);
				}
			}
		}
	}

	/**
	 * @Title: getAvgCount
	 * @Description: TODO 计算俩个词之间 }{ 的平均个数
	 * @param w1
	 * @param w2
	 * @param c1
	 * @param c2
	 * @param sentence
	 * @return
	 * @return double
	 * @author HeYan
	 */
	public final double getAvgCount(String w1, String w2, int c1, int c2, String sentence) {
		List<Integer> list1 = new ArrayList<>();
		List<Integer> list2 = new ArrayList<>();
		String temp = "";
		int first = 0;
		for (int i = 0; i < c1; i++) {
			if (i != 0) {
				temp = sentence.substring(first + w1.length());
				int t = first;
				first = temp.indexOf(w1);
				list1.add(first + t + w1.length());
			} else {
				temp = sentence;
				first = temp.indexOf(w1);
				list1.add(first);
			}
		}
		first = 0;
		temp = "";
		for (int i = 0; i < c2; i++) {
			if (i != 0) {
				temp = sentence.substring(first + w2.length());
				int t = first;
				first = temp.indexOf(w2);
				list2.add(first + t + w2.length());
			} else {
				temp = sentence;
				first = temp.indexOf(w2);
				list2.add(first);
			}
		}
		/* 计算 */
		double sum = 0;
		for (int i : list1) {
			for (int j : list2) {
				int begin = i >= j ? j : i;
				int end;
				if (i >= j) {
					end = i;
					sum += sentence.substring(begin, end + w1.length()).split("\\}\\{").length - 1;
				} else {
					end = j;
					sum += sentence.substring(begin, end + w2.length()).split("\\}\\{").length - 1;
				}
			}
		}
		return sum / (c1 * c2);
	}

	public void insertRes(String w1, String w2, double res) {
		PreparedStatement ps = null;
		String sql = "INSERT INTO relationship(word1,word2,p) VALUES(?,?,?)";
		try {
			ps = conn.prepareStatement(sql);
			ps.setString(1, w1);
			ps.setString(2, w2);
			ps.setDouble(3, res);
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public void run() {
		try {
			readFileContent();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println(tablename);
	}

	public static void main(String[] args) {
		ExecutorService fix = Executors.newFixedThreadPool(30);
		Connection conn = ConnectionPool.getConnection("word2vec", "localhost");
		CalculateWord cal = new CalculateWord("", conn);
		List<String> tables = cal.getTables();
		for (String table : tables) {
			fix.execute(new CalculateWord(table, conn));
		}
		fix.shutdown();
	}
}
